package com.meichuang.meipian.video.nativejni;

import android.content.Context;
import android.util.Log;

import com.meichuang.meipian.video.decode.MediaCodecDecode;
import com.meichuang.meipian.video.log.LogUtil;
import com.meichuang.meipian.video.music.MusicUtil;
import com.meichuang.meipian.video.textbitmap.BitmapTextUtil;

import org.json.JSONObject;

/**
 * Created by ken on 17/11/11.
 */

public class VideoNative {
    public VideoNative(){
        LogUtil.w("VideoNative  VideoNative  new \n");
    }
    static {
        System.loadLibrary("avcodec");
        System.loadLibrary("avdevice");
        System.loadLibrary("avfilter");
        System.loadLibrary("avformat");
        System.loadLibrary("avutil");
        System.loadLibrary("fdk-aac");
        System.loadLibrary("swresample");
        System.loadLibrary("swscale");
        System.loadLibrary("meipianengine");
    }
    public interface NativeCallBack{
        public abstract void event(int event,String message);
        public abstract String getScanJson(String id);
        public abstract void updateRender(int thisFrame);
    }
    public static final String LOGTAG = "VideoEngine";
    public static int ENGINE_EVENT_UNKNOW=0;//未知
    public static int ENGINE_EVENT_SEARCHDATAWITHID = 1;//根据id插值模板路径
    public static int ENGINE_EVENT_VIDEORENDEREND = 2;//渲染结束通知
    public static int ENGINE_EVENT_DRAWTEXTPICTURE = 3;//文字绘制到图片并绑定纹理事件
    public static int ENGINE_EVENT_PLAYEMUSIC = 4;//播放音乐时候需要
    public static int  ENGINE_EVENT_MUSIC_ENCODE_END = 5;//音乐处理完毕
    public static int  ENGINE_EVENT_FILE_BITMAP_TEXTURE = 6;//加载文件生成图片

//    public static int  ENGINE_EVENT_RENDEREND = 5;//渲染结束
    //    public enum EngineEvent {
//        ENGINE_EVENT_UNKNOW,//未知
//        ENGINE_EVENT_SEARCHDATAWITHID,//根据id插值模板路径
//        ENGINE_EVENT_VIDEORENDEREND,//渲染结束通知
//        ENGINE_EVENT_DRAWTEXTPICTURE,//文字绘制到图片并绑定纹理事件
//        ENGINE_EVENT_PLAYEMUSIC,//播放音乐时候需要
//    }
    public  native String stringFromJNI();
    public  native long getInstance();
    public  native void initGLView(long handler,int w,int h);//初始化view大小的时候
    public  native void updateRender(long handler);//每一帧渲染调用
    public  native void setPathList(long handler,String mainBundleResourcePathROOT,String currentSceneGroupUserResourcePathROOT,
                                    String multiSceneRootROOT,String multiSceneSceneROOT,String multiSceneUserResourcesROOT,String multiSceneTemplateROOT,
                                    String assetsPath,boolean isClearShuiying);//传入各种路径
    public  native void setUserMapConifg(long handler,String json);
    public  native void deleteRender(long handler);//释放底层
    public  native void setRenderModelAndFrame(long handler,int renderModelType,int frame,int total,String musicPath);
    public  native int getRenderFram(long handler);
    public  native int encodeMP3(String path);
    public  static native void checkPakege(Context context);

    public static native int cutMp4(String inputfile,String outputfile,String positioninfo,String startTime,String endTime);
    public static native int videoToMp3(String inputfile,String outputfile,String positioninfo,String startTime,String endTime);
    public static native int cutMp3(String inputfile,String outputfile,String positioninfo,String startTime,String gadtime);
    public static native int m4aToMp3(String inputfile,String outputfile,String positioninfo,String startTime,String gadtime);

    public static native void setFFmpegUseMediacodec(int type);
    public static native byte[] pullPcmData(int length);
    public static native void H264AACMuxer(String mp4file,String aacfile,String outputfile);

    public static native float getEngineVersion();
    private NativeCallBack mNativeCallBack = null;
    public void setNativeCallBack(NativeCallBack obj){
        this.mNativeCallBack = obj;
    }
    public String nativeCallBackFromRender(int event,String str){
        LogUtil.i(LOGTAG,"type:"+event+"   nativeCallBackFromRender:"+str);
        if(event == ENGINE_EVENT_SEARCHDATAWITHID){
            try{
                return getMobanPath(str);
            }catch(Exception e){
                e.printStackTrace();
            }
        }else if(event == ENGINE_EVENT_DRAWTEXTPICTURE){
            String json =  BitmapTextUtil.textToBitmapAndBindTexture(str);
            return json;
        }else if(event == ENGINE_EVENT_PLAYEMUSIC){
            return  MusicUtil.musicStatusChange(str);
        }else if(event == ENGINE_EVENT_VIDEORENDEREND){//渲染结束
            if(mNativeCallBack != null){
                mNativeCallBack.event(event,str);
            }
            return "nativeCallBackFromRender renderend true";
        }else if(event == ENGINE_EVENT_MUSIC_ENCODE_END){
            if(mNativeCallBack != null){
                mNativeCallBack.event(event,str);
            }
            return "nativeCallBackFromRender music true";
        }else if(event == ENGINE_EVENT_FILE_BITMAP_TEXTURE){
            String path = "";
            int textureId = -1;
            try {
                JSONObject object=new JSONObject(str);
                path = object.getString("file");
                textureId = object.getInt("textureId");
            }catch (Exception e){
                e.printStackTrace();
            }
            String json = BitmapTextUtil.fileToBitmapToTexture(path,textureId);
            return json;//"nativeCallBackFromRender ENGINE_EVENT_FILE_BITMAP_TEXTURE true";
        }
        return "nativeCallBackFromRender true";
    }

    public String getMobanPath(String id) {

        if(mNativeCallBack != null){
           return mNativeCallBack.getScanJson(id);
        }

        try{
            JSONObject object=new JSONObject();
//        JSONArray jArray = new JSONArray();
            object.put("sceneJsonPath", "aaa");
            object.put("sId" , "50130");
            object.put("sceneResourceFolderPath", "/sdcard/");
            object.put("width", 640);
            object.put("height", 480);
            String s =  object.toString();
            Log.w(LOGTAG,"   nativeCallBackFromRender:s  : "+s );
            return s;
        }catch(Exception e){
            e.printStackTrace();
        }
        return "";
    }
    public int mediacodecInit(long avMediaReaderId,int textureid_mediacodec,int mimetype, int width, int height, byte[] csd0, byte[] csd1){
       return new MediaCodecDecode().mediacodecInit( avMediaReaderId, textureid_mediacodec, mimetype,  width,  height, csd0, csd1);
    }
    public int mediacodecDecode(long avMediaReaderId,byte[] bytes, int size, int pts) {
//        LogUtil.w("mediacodecDecode avMediaReaderId "+avMediaReaderId);
        MediaCodecDecode obj = MediaCodecDecode.mapMedia.get(Long.valueOf(avMediaReaderId));
        if(obj!=null){
            return obj.mediacodecDecode(bytes,  size,  pts);
        }
        return 0;
    }
//    public void updateRenderMedia(long avMediaReaderId){//更新纹理
//        MediaCodecDecode.mapMedia.get(Long.valueOf(avMediaReaderId)).updateRender();
//    }
    public void stop(long avMediaReaderId){
        LogUtil.w("mediacodecDecode stop  stop stop "+avMediaReaderId);
        MediaCodecDecode obj = MediaCodecDecode.mapMedia.get(Long.valueOf(avMediaReaderId));
        if(obj!=null){
            obj.stop();
            MediaCodecDecode.mapMedia.remove(Long.valueOf(avMediaReaderId));
        }
    }






    //剪辑新增接口
    //整个场景定位到某个位置
    public  native void seekFramaTime(long handler,int fpsThis);
    //设置播放状态 1 暂停  0 播放 等
    public  native void setPlayStatus(long handler,int status);
    public  native int getPlayStatus(long handler);
    //设置素材是否需要解码
    public  native void setisDecodeFile(long handler,boolean decode);
    public  native boolean getIsDecodeFile(long handler);
    //剪辑相关api
    //加入一个媒体
    //创建一个场景 true为剪辑状态 false为导出视频状态或者模板预览或者导出视频状态
    public native void setCutStatus(long handler,boolean b);
    public  native long creatScene(long handler,String json);
    public  native boolean updateScene(long handler,long sceneId,String json);
    public  native boolean updateBackground(long handler,long sceneId,String json);

    //音乐相关操作
    public  native long createMusic(long handler,String json);
    public  native boolean deleteMusic(long handler,long musicId);
    public  native long updateMusic(long handler,long musicId,String json);
    //更新音频的其他效果的关键帧动画 json格式右上
    public  native boolean updateMusicEffectAnim(long handler,long musicId,int type,String json);
    //当前音频的滤镜/混合模式改变了 或者对应的强度或者值改变
    public  native boolean updateMusicEffect(long handler,long musicId,int type,String json);
    //更新音频的相关特效的值 如果有关键帧动画 则此值不起作用
    public  native boolean updateMusicEffectValue(long handler,long musicId,int type,float value);
    //type具体值含义见文档

    //视频相关操作
    public  native long createVideo(long handler,String json); //添加一个视频
    public  native boolean deleteVideo(long handler,long videoId);
    public  native long updateVideo(long handler,long videoId,String json);//更新视频相关信息 比如位置 没有关键帧的情况下
    public  native boolean updateVideoAnim(long handler,long videoId,String json);//更新视频的关键帧动画
    //更新视频的其他效果的关键帧动画
    public  native boolean updateVideoEffectAnim(long handler,long videoId,int type,String json);
    //    //更新视频的相关特效的值 如果有关键帧动画 则此值不起作用
    //    bool updateVideoEffectValue(long videoId,int type,float value);
    //当前视频的滤镜/混合模式改变了
    public  native boolean updateVideoEffect(long handler,long videoId,int type,String json);
    //    bool addEffect(long videoId,string json);//添加 前期不用
    //更新滤镜/混合 filterType使用那个滤镜 或者 那种混合模式


    //文字相关操作
    public  native long createText(long handler,String json);
    public  native long updateText(long handler,long textId,String json);
    public  native boolean deleteText(long handler,long textId);
    public  native boolean updateTextAnim(long handler,long videoId,String json);
    //更新其他效果的关键帧动画 json格式右上
    public  native boolean updateTextffectAnim(long handler,long videoId,int type,String json);
    //当前透明度 效果 动画 设置
    public  native boolean updateTextEffect(long handler,long videoId,int type,String json);
//    //更新值  该接口目前不可用
//    public  native boolean updateTextEffectValue(long handler,long videoId,int type,float value);

    //end


}
